home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / crcset11.zip / VALIDCRC.PAS < prev    next >
Pascal/Delphi Source File  |  1990-11-16  |  3KB  |  170 lines

  1. {$I-}
  2. {
  3. VALIDCRC.PAS
  4.  
  5. Kevin Dean
  6. Fairview Mall P.O. Box 55074
  7. 1800 Sheppard Avenue East
  8. Willowdale, Ontario
  9. CANADA    M2J 5B9
  10. CompuServe ID: 76336,3114
  11.  
  12. November 16, 1990
  13.  
  14.     This module validates the CRC of the program in which it is linked.
  15. The code was designed as an anti-virus algorithm.  The CRC is a very effective
  16. method of detecting viruses; any virus that attaches itself to the program
  17. changes the CRC of the program.  The response to an invalid CRC is entirely up
  18. to the programmer.
  19.  
  20.     This code is public domain.
  21. }
  22.  
  23.  
  24. unit ValidCRC;
  25.  
  26.  
  27. interface
  28.  
  29.  
  30. uses
  31.   DOS;
  32.  
  33.  
  34. type
  35.   crc32_t =
  36.     longint;
  37.  
  38.   FileCRC =
  39.     record
  40.     case boolean of
  41.       false:
  42.     (
  43.     SearchStr : array [1 .. 8] of char;    { String to search for. }
  44.     );
  45.  
  46.       true:
  47.     (
  48.     Polynomial : crc32_t;            { Polynomial for this file. }
  49.     CRC : crc32_t;                { Calculated CRC for this file. }
  50.     )
  51.     end;
  52.  
  53.  
  54. function IsValidCRC(ProgName : string) : boolean;
  55.  
  56.  
  57. implementation
  58.  
  59.  
  60. const _VirusCRC : FileCRC =
  61.   (
  62.   SearchStr : ('D', 'E', 'A', 'N', '_', 'C', 'R', 'C')
  63.   );
  64.  
  65.  
  66. type
  67.   dwordrec =
  68.     record
  69.     Lo, Hi : word
  70.     end;
  71.  
  72.  
  73. {***}
  74. { Extract the low word of a dword. }
  75. function LowW(dword : longint) : word;
  76.  
  77. begin
  78. LowW := (dwordrec(dword)).Lo
  79. end;
  80.  
  81.  
  82. {***}
  83. { Extract the high word of a dword. }
  84. function HiW(dword : longint) : word;
  85.  
  86. begin
  87. HiW := (dwordrec(dword)).Hi
  88. end;
  89.  
  90.  
  91. {***}
  92. { Calculate CRC of active program and compare it to CRC in _VirusCRC. }
  93. function IsValidCRC(ProgName : string) : boolean;
  94.  
  95. var
  96.   PN : string;                { Program name. }
  97.   Buffer : array [1 .. 1024] of byte;    { Buffer for file's data. }
  98.   Table : array [0 .. 255] of crc32_t;    { CRC table. }
  99.   I : word;                { Byte counter. }
  100.   HalfI : ^crc32_t;            { Pointer to CRC of I div 2. }
  101.   CRC : crc32_t;            { Current CRC. }
  102.   ProgFile : file;            { Program file. }
  103.   BufPtr : ^byte;            { Pointer to Buffer. }
  104.  
  105. begin
  106. if Lo(DosVersion) < 3 then
  107.   { Search PATH for program file. }
  108.   PN := FSearch(ProgName, GetEnv('PATH'))
  109. else
  110.   { Under DOS versions 3 and above, the program name is in ParamStr(0). }
  111.   PN := ParamStr(0);
  112.  
  113. if _VirusCRC.Polynomial <> 0 then
  114.   begin
  115.   Assign(ProgFile, PN);
  116.   Reset(ProgFile, 1);
  117.  
  118.   if IOResult = 0 then
  119.     begin
  120.     { Generate a CRC lookup table for faster calculation. }
  121.     HalfI := @Table[0];
  122.     Table[0] := 0;
  123.     I := 0;
  124.     while I < 256 do
  125.       begin
  126.       if Hi(HiW(HalfI^)) and $80 = $80 then
  127.     begin
  128.     Table[I + 1] := HalfI^ shl 1;
  129.     Table[I] := Table[I + 1] xor _VirusCRC.Polynomial
  130.     end
  131.       else
  132.     begin
  133.     Table[I] := HalfI^ shl 1;
  134.     Table[I + 1] := Table[I] xor _VirusCRC.Polynomial
  135.     end;
  136.  
  137.       Inc(I, 2);
  138.       Inc(longint(HalfI), sizeof(crc32_t))
  139.       end;
  140.  
  141.     CRC := 0;
  142.     BlockRead(ProgFile, Buffer, sizeof(Buffer), I);
  143.     while I <> 0 do
  144.       begin
  145.       BufPtr := @Buffer[1];
  146.       while I <> 0 do
  147.     begin
  148.     CRC := (CRC shl 8) xor Table[Hi(HiW(CRC)) xor BufPtr^];
  149.  
  150.     Dec(I);
  151.     Inc(longint(BufPtr))
  152.     end;
  153.  
  154.       BlockRead(ProgFile, Buffer, sizeof(Buffer), I)
  155.       end;
  156.  
  157.     Close(ProgFile);
  158.     IsValidCRC := CRC = _VirusCRC.CRC
  159.     end
  160.   else
  161.     { If unable to open program file, assume CRC is invalid. }
  162.     IsValidCRC := false
  163.   end
  164. else
  165.   { CRC polynomial must be something other than 0. }
  166.   IsValidCRC := false
  167. end;
  168.  
  169.  
  170. end.